home *** CD-ROM | disk | FTP | other *** search
/ DOpus Plus / DOpus Plus.iso / Tutorial / C Guide / Simple_Module2 / DetachWindow / DetachWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-31  |  9.5 KB  |  289 lines

  1. /*******************************************************************
  2.  
  3.    DetachWindow.c
  4.     
  5.     Does detach itself from the starting process and open a simple
  6.     window with some easy gadgets.
  7.     
  8.     To do this detaching we need 2 functions more and since I want
  9.     not change our ModuleEntry.c for this, I must name the first
  10.     function OwnWindow(). 
  11.     
  12.     You may also refer to the IconClock module of the SDK for 
  13.     an other example.
  14.     
  15.     Use ARTM, SnoopDos or similar if you want to check, that really
  16.     an own process is running...                
  17.                     
  18. *********************************************************************/
  19. #define PARENT
  20. #include "/includes/Window.h"
  21.  
  22. // now we need some other variables than in our structure
  23. // WindowHandle...
  24.  
  25. typedef struct _PassingData
  26. {
  27.     ULONG a4;                 // to store a4 (module is a4 relative)
  28.     struct Library *library;  // to store a pointer to dopus5.library 
  29.     struct Library *module;   // to store a pointer to this module
  30.     IPCData *ipc;             // to store our NEW handle
  31.     
  32.     char args[256];           // since we want to use the args in our
  33.                               // detached process, we have to copy it
  34.     
  35.     struct Screen *screen;
  36. }  PassingData;
  37.  
  38. /********************************************************************/
  39. // locale prototypes
  40.  
  41. ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
  42.                                        register __a1 PassingData *pd );
  43.                                                     
  44. void __saveds New_Proc( void );
  45.  
  46. BOOL OpenDOpusWin( WindowHandle *wh );  // function not changed
  47.  
  48. BOOL HandleWindow( WindowHandle *wh );  // function not changed
  49.  
  50. /********************************************************************/
  51. // this is not the same function like before !
  52. // it is the first special function we need...
  53.  
  54. void OwnWindow( STRPTR args, struct Screen *screen )
  55. {
  56.     IPCData *new_proc = NULL;
  57.     PassingData *pd;
  58.     
  59.     if( (pd = AllocMemH(mempool, sizeof(PassingData))) ) // allocate some memory
  60.       {
  61.           pd->screen = screen;          // store the screen pointer
  62.           strcpy( pd->args, args );     // store our arguments
  63.           
  64.           // now some special stuff, but everything is needed here...
  65.           pd->a4      = getreg( REG_A4 ); 
  66.           pd->module  = (struct Library *) getreg( REG_A6 );
  67.           pd->library = DOpusBase;
  68.           
  69.           // now we are ready to call IPC_Launch()
  70.           IPC_Launch( 0, 
  71.                       &new_proc,        // pointer to pointer to the IPC of the new process, for storing...
  72.                           "ExampleWindow",  // name of the new process
  73.                           (ULONG) New_Proc, // entrypoint of the new process
  74.                           4096,             // stack to use
  75.                           (ULONG) pd,       // data to pass to the new process
  76.                           DOSBase );        // pointer to dos.library
  77.                           
  78.             if( !new_proc )              // if detaching failed...
  79.                  FreeMemH( pd );
  80.         }
  81. }
  82.  
  83. // let's do now the second special function
  84.  
  85. ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
  86.                                        register __a1 PassingData *pd )
  87. {
  88.     // you may use this function also to setup things for your
  89.     // main process, but you should not call any IPC functions here !
  90.     // we do only the minimum required..., but you will get some small
  91.     // warnings from your compiler. Just ignore them now - they does
  92.     // not appear, if we would do here some more things... 
  93.     
  94.     struct Library *DOpusBase; 
  95.  
  96.     // fix A4
  97.     putreg( REG_A4, pd->a4 );
  98.  
  99.     // store IPC pointer
  100.     pd->ipc = ipc;
  101.  
  102.     // get dopus.library - one warning now
  103.     DOpusBase = pd->library;
  104.  
  105.    // now may follow your initialization
  106.     
  107.     // if something fails and you must quit, you should do:
  108.     // return FALSE;
  109.  
  110.    // increase our library counter, so we can not be flushed
  111.     // do not forget to decrease it, if your detached process ends 
  112.     pd->module->lib_OpenCnt++;
  113.     
  114.     return TRUE; // all was successfully
  115.     
  116.  
  117. void __saveds New_Proc( void )
  118. {
  119.     // this is now just the same like until now our OwnWindow() function
  120.     
  121.     WindowHandle          *wh;
  122.     PassingData           *pd;
  123.     STRPTR                 args;
  124.     IPCData               *ipc;
  125.     struct Library        *DOpusBase;
  126.     
  127.     // but we must do some additional things 
  128.     
  129.     // get dopus library
  130.     if( !(DOpusBase = (struct Library *) FindName(&((struct ExecBase *)*((ULONG *)4))->LibList, "dopus5.library")) )
  131.         return;
  132.     
  133.     // do startup
  134.     ipc = IPC_ProcStartup( (ULONG *) &pd, New_Proc_Startup );
  135.  
  136.     // fix A4 so we can access global data in the module (eg library bases)
  137.     putreg( REG_A4, pd->a4 );
  138.  
  139.     // something failed until now ?
  140.     if( !ipc )
  141.     {
  142.         if( pd )
  143.           {
  144.               IPC_Free( pd->ipc ); // possible it has a value here 
  145.              FreeMemH( pd );      // free our memory
  146.           }
  147.               
  148.         return;
  149.     }
  150.         
  151.     if( (wh = AllocMemH(mempool, sizeof(WindowHandle))) ) // allocate some memory
  152.       {
  153.           // we copy now our values, if you allocate for launching the real
  154.          // structure you need, you must not do this of course... :)
  155.  
  156.          
  157.           wh->screen = pd->screen;     // store the screen pointer
  158.           strncpy( wh->buffer, pd->args, 30 ); // copy our args - limited through our size of wh->buffer...
  159.           wh->buffer[30] = NULL;       // terminate our string
  160.           args = wh->buffer;
  161.           
  162.           // now we can free our PassingData...
  163.           FreeMemH( pd );
  164.           
  165.           // now it is really the same excluding the end ...
  166.           
  167.           if( OpenDOpusWin(wh) )   // open the window
  168.            {
  169.                  // we copy now the arguments into the text gadget
  170.                // if we have supplied some...
  171.                  
  172.                SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) args );
  173.                                                    
  174.                while( TRUE ) 
  175.                   {
  176.                         // I use here Wait(), so it is easier with the changes
  177.                  
  178.                       wh->signals = Wait( 1 << wh->win->UserPort->mp_SigBit );   // wait for window events
  179.                                                         
  180.                       if( wh->signals & 1 << wh->win->UserPort->mp_SigBit )
  181.                             if( HandleWindow(wh) )
  182.                                    break;        // does end the while loop                                       
  183.                      
  184.                   }
  185.              
  186.                CloseConfigWindow( wh->win ); 
  187.              }
  188.              
  189.           FreeMemH( wh ); // free our memory
  190.       }
  191.     
  192.     // since we are here a detached process, we must do some other cleanup too
  193.     IPC_Free( ipc );
  194.     
  195.     // and decrease our Library access counter, since we have increased it before
  196.     ( (struct Library *) getreg(REG_A6) )->lib_OpenCnt--;   
  197.                             
  198. }
  199.  
  200. /********************************************************************/
  201. // This function does open our window. We could have done this in the
  202. // function OwnWindow() too, but we need this function later again.
  203.  
  204. BOOL OpenDOpusWin( WindowHandle *wh )
  205. {
  206.     NewConfigWindow ncfgwin;     // we need a NewConfigWindow structure too
  207.                                  // of couse you could also allocate it with
  208.                                           // AllocMemH()...
  209.     
  210.     // and have to fill it
  211.     
  212.     ncfgwin.nw_Parent = wh->screen;  // open on this screen
  213.     
  214.     // getting a localized title...
  215.     ncfgwin.nw_Title  = DOpusGetString( locale, MSG_WINDOW_TITLE );
  216.     
  217.     ncfgwin.nw_Dims   = &cfgwin; // a pointer to the ConfigWin structure
  218.     ncfgwin.nw_Locale = locale;  // the module locale pointer (from modinit.c)
  219.     ncfgwin.nw_Port   = NULL;    // we doesn't supply a port
  220.     ncfgwin.nw_Font   = NULL;    // just taking the screen font
  221.     ncfgwin.nw_Flags  = WINDOW_REQ_FILL      | // fill with stripple pattern
  222.                         WINDOW_AUTO_KEYS     | // handle keys automatic
  223.                               WINDOW_SCREEN_PARENT;  // nw_Parent points to a screen
  224.     
  225.     if( (wh->win = OpenConfigWindow(&ncfgwin)) )   // open the window
  226.       {
  227.           if( (wh->olist = AddObjectList(wh->win, odef)) ) // add the gadgets
  228.                   return TRUE;
  229.                     
  230.           CloseConfigWindow( wh->win );    //    in error case do not forget :-)
  231.       }
  232.     
  233.     return FALSE;
  234. }
  235.  
  236.  
  237. /********************************************************************/
  238. // we does only close the window, if the closegadget was pressed
  239. // if you want to close it within a gadget, you must only in the
  240. // right case set "stop" to TRUE
  241.  
  242. BOOL HandleWindow( WindowHandle *wh )
  243. {
  244.      BOOL stop = FALSE;
  245.      ULONG value;
  246.      
  247.      while( !stop && (wh->imsg = GetWindowMsg(wh->win->UserPort)) )
  248.         {
  249.             switch( wh->imsg->Class )  // let's handle the IDCMP
  250.               {
  251.                   case IDCMP_GADGETUP:
  252.                                           switch( GET_ID(wh->imsg) )
  253.                                          {
  254.                                                          case GADGET_ID_CYCLE:  // we copy simply the same text to the text gadget
  255.             
  256.                                                                      value = GetGadgetValue( wh->olist, GADGET_ID_CYCLE ) + MSG_CLICK_ME;
  257.                                                                             SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, value) );
  258.                                                                             break;
  259.             
  260.                                               case GADGET_ID_OKAY:   // doing a message
  261.                                                                      
  262.                                                                                         SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_OKAY_DONE) );
  263.                                                                             break;
  264.                                                      
  265.                                               case GADGET_ID_CANCEL: 
  266.                                                                      SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_CANCEL_DONE) );
  267.                                                                             break;
  268.                                           }
  269.                                                                  
  270.                                                   break;
  271.                                      
  272.                   case IDCMP_CLOSEWINDOW:
  273.                                           // we can not simply return here, the IntuiMessage must replied first
  274.                                                   
  275.                                                stop = TRUE;
  276.                                                   break;                                     
  277.               }
  278.                                  
  279.             ReplyWindowMsg( wh->imsg );  
  280.                               
  281.             // remember: You should not use any other routines
  282.             // to get/reply the messages of this window than
  283.             // GetWindowMsg() and ReplyWindowMsg() !!
  284.        }
  285.                                
  286.     return stop;
  287. }
  288.